package com.example.endusation.service.impl;

import com.example.endusation.dao.DiscreteMathDAO;
import com.example.endusation.dao.IdeologicalPoliticsDAO;
import com.example.endusation.dto.*;
import com.example.endusation.entity.DialogueDO;
import com.example.endusation.entity.DialogueDetilDO;
import com.example.endusation.milvus.EmbeddingService;
import com.example.endusation.milvus.MilvusService;
import com.example.endusation.rag.DiscreteMathRagService;
import com.example.endusation.service.DiscreteMathService;
import com.example.endusation.stanford.CoreNlpService;
import com.example.endusation.util.DateUtil;
import com.example.endusation.util.RandomUtil;
import com.example.endusation.util.WrapperResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;


import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class DiscreteMathServiceImpl implements DiscreteMathService {
    @Autowired
    private DiscreteMathDAO discreteMathDAO;
    @Autowired
    private DiscreteMathRagService ragService;
    @Autowired
    private CoreNlpService coreNlpService;
    @Autowired
    private IdeologicalPoliticsDAO ideologicalPoliticsDAO;
    @Value("${document_url}")
    private String UPLOAD_BASE_DIR;
    @Autowired
    private EmbeddingService embeddingService;
    @Autowired
    private MilvusService milvusService;
    private static final String VIDEO = "video";
    private static final String DOCUMENT = "document";

    @Override
    public WrapperResponse talk(AITalkDTO aiTalkDTO) {
        if (aiTalkDTO.getId() == null) {
            String id = DateUtil.getEightLength() + RandomUtil.getFour();
            DialogueDO dialogueDO = new DialogueDO(id, aiTalkDTO.getQuestion(), aiTalkDTO.getUsername());
            int result = discreteMathDAO.insertDialogue(dialogueDO);
            if (result > 0) {
                aiTalkDTO.setId(id);
            }
        }
        DialogueDO dialogueDO = new DialogueDO(aiTalkDTO.getId(), aiTalkDTO.getQuestion(), aiTalkDTO.getUsername());
        discreteMathDAO.updateDialogue(dialogueDO);
        String dialogueDetilId = DateUtil.getEightLength() + RandomUtil.getFour();
        String timestapm = DateUtil.getEightLength();
        DialogueDetilDO dialogueDetilDO = new DialogueDetilDO(dialogueDetilId, "user", aiTalkDTO.getQuestion(), timestapm, aiTalkDTO.getId());
        discreteMathDAO.insertDialogueDetil(dialogueDetilDO);


        String question = aiTalkDTO.getQuestion();
        if (question == null || question.trim().isEmpty()) {
            return WrapperResponse.fail("问题不能为空");
        }
        DialogueDetilDO dialogueDetilDO2 = new DialogueDetilDO();
        String responseJudge = ragService.answerQuestionJudge(question);
        if (responseJudge.equals("4")) {
            //分词
            List<String> tokens = coreNlpService.chineseTokenize(question);
            //调用rag
            String response = ragService.answerQuestion(question, tokens);
            dialogueDetilId = DateUtil.getEightLength() + RandomUtil.getFour();
            timestapm = DateUtil.getEightLength();
            DialogueDetilDO dialogueDetilDO1 = new DialogueDetilDO(dialogueDetilId, "assistant", response, timestapm, aiTalkDTO.getId());
            discreteMathDAO.insertDialogueDetil(dialogueDetilDO1);
            for (String s : tokens) {
                List<IdeologicalPoliticsDTO> result = ideologicalPoliticsDAO.query(s);
                for (IdeologicalPoliticsDTO ideologicalPoliticsDTO : result) {
                    response = response + "\n" + ideologicalPoliticsDTO.getContent();
                }
            }
            setResponse(dialogueDetilDO2, response, aiTalkDTO, "4", null);
        } else {
            if (responseJudge.equals("1")) {
                try {
                    List<MilvusService.QueryResult> s = milvusService.search("推荐离散数学图知识点视频", embeddingService, 1, VIDEO);
                    setResponse(dialogueDetilDO2, "为您找到以下视频", aiTalkDTO, "1", s.get(0).getSourceFile());
                } catch (Exception e) {
                    setResponse(dialogueDetilDO2, "未找到相关视频", aiTalkDTO, "4", null);
                }


            } else if (responseJudge.equals("2")) {
                setResponse(dialogueDetilDO2, "11", aiTalkDTO, "2", null);
            } else if (responseJudge.equals("3")) {
                setResponse(dialogueDetilDO2, "为您找到以下资料", aiTalkDTO, "3", "/uploaded/ziliao/101 集合.pdf");
            }
        }


        return WrapperResponse.success(dialogueDetilDO2);
    }

    @Override
    public WrapperResponse queryDialogue(AITalkDTO aiTalkDTO) {
        List<DialogueDTO> list = discreteMathDAO.queryDialogue(aiTalkDTO.getUsername());
        return WrapperResponse.success(list);
    }

    @Override
    public WrapperResponse queryDiaLogueDetil(AITalkDTO aiTalkDTO) {
        List<DialogueDetilDO> list = discreteMathDAO.queryDialogueDetil(aiTalkDTO.getId());
        return WrapperResponse.success(list);
    }

    @Override
    public WrapperResponse insertDiaLogue(AITalkDTO aiTalkDTO) {
        String id = DateUtil.getEightLength() + RandomUtil.getFour();
        DialogueDO dialogueDO = new DialogueDO(id, aiTalkDTO.getQuestion(), aiTalkDTO.getUsername());
        discreteMathDAO.insertDialogue(dialogueDO);
        return WrapperResponse.success(dialogueDO);
    }

    @Override
    public WrapperResponse uploadFile(AITalkDTO aiTalkDTO) {
        try {
            // 1. 创建按日期分类的文件夹（避免文件过多）
            String dateDir = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String saveDir = UPLOAD_BASE_DIR + dateDir + "/";
            File dir = new File(saveDir);
            if (!dir.exists()) {
                dir.mkdirs();  // 递归创建目录
            }

            // 2. 生成唯一文件名（避免重名覆盖）
            String originalFileName = aiTalkDTO.getFile().getOriginalFilename();
            String fileExt = originalFileName.substring(originalFileName.lastIndexOf("."));  // 获取文件扩展名
            String uniqueFileName = UUID.randomUUID().toString() + fileExt;  // 用UUID生成唯一文件名

            // 3. 保存文件到本地硬盘
            Path savePath = Paths.get(saveDir + uniqueFileName);
            Files.write(savePath, aiTalkDTO.getFile().getBytes());  // 写入文件

            // 4. 构建文件访问路径（可选：如果需要前端访问，可返回相对路径）
            String fileUrl = "/uploaded/" + dateDir + "/" + uniqueFileName;  // 前端访问的URL路径
            UpLoadFileResponseDTO upLoadFileResponseDTO = new UpLoadFileResponseDTO();
            upLoadFileResponseDTO.setFileName(originalFileName);
            upLoadFileResponseDTO.setFileSize(aiTalkDTO.getFile().getSize());
            upLoadFileResponseDTO.setFileUrl(fileUrl);
            upLoadFileResponseDTO.setSavePath(savePath.toString());
            return WrapperResponse.success(upLoadFileResponseDTO);
        } catch (IOException e) {
            e.printStackTrace();
            return WrapperResponse.fail("false");
        }
    }

    @Override
    public WrapperResponse talkWithFile(AITalkDTO aiTalkDTO) {
        if (aiTalkDTO.getId() == null) {
            String id = DateUtil.getEightLength() + RandomUtil.getFour();
            DialogueDO dialogueDO = new DialogueDO(id, aiTalkDTO.getQuestion(), aiTalkDTO.getUsername());
            int result = discreteMathDAO.insertDialogue(dialogueDO);
            if (result > 0) {
                aiTalkDTO.setId(id);
            }
        }
        DialogueDO dialogueDO = new DialogueDO(aiTalkDTO.getId(), aiTalkDTO.getQuestion(), aiTalkDTO.getUsername());
        discreteMathDAO.updateDialogue(dialogueDO);
        String dialogueDetilId = DateUtil.getEightLength() + RandomUtil.getFour();
        String timestapm = DateUtil.getEightLength();
        DialogueDetilDO dialogueDetilDO = new DialogueDetilDO(dialogueDetilId, "user", aiTalkDTO.getQuestion(), timestapm, aiTalkDTO.getId());
        discreteMathDAO.insertDialogueDetil(dialogueDetilDO);


        String question = aiTalkDTO.getQuestion();
        if (question == null || question.trim().isEmpty()) {
            return WrapperResponse.fail("问题不能为空");
        }
        if (question.substring(0, 4).equals("ai阅卷")) {
            try {
                String imageFile = UPLOAD_BASE_DIR + aiTalkDTO.getFileUrl();
                FileInputStream fileInputStream = new FileInputStream(imageFile);
                BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
                byte[] buffer = new byte[1024]; // 缓冲区（1KB）
                int len;
                while ((len = bufferedInputStream.read(buffer)) != -1) {

                }
            } catch (FileNotFoundException e) {

            } catch (IOException e) {

            }
        }
        List<String> tokens = coreNlpService.chineseTokenize(question);
        String response = ragService.answerQuestion(question, tokens);

        dialogueDetilId = DateUtil.getEightLength() + RandomUtil.getFour();
        timestapm = DateUtil.getEightLength();
        DialogueDetilDO dialogueDetilDO1 = new DialogueDetilDO(dialogueDetilId, "assistant", response, timestapm, aiTalkDTO.getId());
        discreteMathDAO.insertDialogueDetil(dialogueDetilDO1);
        DialogueDetilDO dialogueDetilDO2 = new DialogueDetilDO();
        dialogueDetilDO2.setDialogueId(aiTalkDTO.getId());
        dialogueDetilDO2.setContent(response);
        return WrapperResponse.success(dialogueDetilDO2);
    }

    public void setResponse(DialogueDetilDO dialogueDetilDO, String response, AITalkDTO aiTalkDTO, String select, String address) {
        dialogueDetilDO.setDialogueId(aiTalkDTO.getId());
        dialogueDetilDO.setContent(response);
        if (select.equals("1")) {
            dialogueDetilDO.setFile(true);
            dialogueDetilDO.setFileType("video");
            dialogueDetilDO.setFileUrl(address);
        } else if (select.equals("2")) {
            dialogueDetilDO.setFile(true);
            dialogueDetilDO.setFileType("graph");
            dialogueDetilDO.setFileUrl(address);
            GraphNode graphNode1 = new GraphNode(1, "离散数学", 1, 20);
            GraphNode graphNode2 = new GraphNode(2, "集合", 2, 15);
            GraphNode graphNode3 = new GraphNode(3, "关系", 2, 15);
            GraphNode graphNode4 = new GraphNode(4, "函数", 2, 15);
            GraphNode graphNode5 = new GraphNode(5, "图", 2, 15);
            GraphNode graphNode6 = new GraphNode(6, "树", 2, 15);
            GraphNode graphNode7 = new GraphNode(7, "命题", 2, 15);
            GraphNode graphNode8 = new GraphNode(8, "谓词", 2, 15);
            List<GraphNode> list1 = new ArrayList<>();
            list1.add(graphNode1);
            list1.add(graphNode2);
            list1.add(graphNode3);
            list1.add(graphNode4);
            list1.add(graphNode5);
            list1.add(graphNode6);
            list1.add(graphNode7);
            list1.add(graphNode8);
            GraphLink graphLink = new GraphLink(1, 2, 2);
            GraphLink graphLink1 = new GraphLink(1, 3, 2);
            GraphLink graphLink2 = new GraphLink(1, 4, 2);
            GraphLink graphLink3 = new GraphLink(1, 5, 2);
            GraphLink graphLink4 = new GraphLink(1, 6, 2);
            GraphLink graphLink5 = new GraphLink(1, 7, 2);
            GraphLink graphLink6 = new GraphLink(1, 8, 2);
            List<GraphLink> list2 = new ArrayList<>();
            list2.add(graphLink);
            list2.add(graphLink1);
            list2.add(graphLink2);
            list2.add(graphLink3);
            list2.add(graphLink4);
            list2.add(graphLink5);
            list2.add(graphLink6);
            GraphDataDTO graphDataDTO = new GraphDataDTO();
            graphDataDTO.setNodes(list1);
            graphDataDTO.setLinks(list2);
            dialogueDetilDO.setGraphData(graphDataDTO);
            dialogueDetilDO.setContent("离散数学章节图谱");
            dialogueDetilDO.setFileName("离散数学章节图谱");
        } else if (select.equals("3")) {
            dialogueDetilDO.setFile(true);
            dialogueDetilDO.setFileType("file");
            dialogueDetilDO.setFileUrl(address);
            dialogueDetilDO.setFileName("离散数学资料");
        } else {
            dialogueDetilDO.setFile(false);
        }


    }

}
